/*******************************************************************************
 * Copyright 2011 Alexandre Zglav and Morphiastic
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.morphiastic.analysis.analyzers;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import org.elasticsearch.common.settings.Settings;
import com.morphiastic.annotations.Analyzer;
import com.morphiastic.annotations.AnalyzerDefinition;
import com.morphiastic.annotations.Parameter;

/**
 * Factory that creataes an ElasticAnalyzer based on an Analyzer Annotations
 * @author Alex
 *
 */
public class ElasticAnalyzerFactory {

	/**
	 * Builds an ElasticAnalyzer object based on an Analyzer annotation
	 * @param analyzerAnnotation
	 * @return
	 */
	public static ElasticAnalyzer getAnalyzerFromAnnotation(Analyzer analyzerAnnotation){
		if(analyzerAnnotation == null ) return null;
		String defName = analyzerAnnotation.defName();
		HashMap<String,String> params = null;
		 
		if(analyzerAnnotation.parameters().length>0){
			params = new HashMap<String, String>();
			for (Parameter parameter : analyzerAnnotation.parameters()) {
				params.put(parameter.key(),parameter.value());
			}
		}
		ElasticAnalyzerType type  = analyzerAnnotation.type();
		return buildAnalyzer(defName, type, params);
	}
	
	
	/**
	 * same as before ... but with AnalyzerDefinition annotation
	 * @param analyzerAnnotation
	 * @return
	 */
	public static ElasticAnalyzer getAnalyzerFromAnnotation(AnalyzerDefinition analyzerAnnotation){
		if(analyzerAnnotation == null ) return null;
		String defName = analyzerAnnotation.defName();
		HashMap<String,String> params = null;
		if(analyzerAnnotation.parameters().length>0){
			params = new HashMap<String, String>();
			for (Parameter parameter : analyzerAnnotation.parameters()) {
				params.put(parameter.key(),parameter.value());
			}
		}
		ElasticAnalyzerType type  = analyzerAnnotation.type();
		return buildAnalyzer(defName, type, params);
	}
	

	/**
	 * Method used to build an ElasticAnalyzer from the 
	 * @param analyzerName
	 */
	public static ElasticAnalyzer getAnalyzerFromSettings(String analyzerName, Settings analyzerSettings){
		 
		String typeVal = analyzerSettings.get("type");

		try {
			ElasticAnalyzerType type = ElasticAnalyzerType.valueOf(typeVal);
			ElasticAnalyzer analyzer = buildAnalyzer(analyzerName, type, null);
			analyzer.setParamsFromSettings(analyzerSettings);
			return analyzer;
		} catch (IllegalArgumentException e) {
			// TODO: handle exception
		}
		
		//special case for language analyzers
		
		Language langType = Language.valueOf(typeVal);
//		ElasticAnalyzerType type = ElasticAnalyzerType.valueOf(typeVal);
		ElasticAnalyzerType type = ElasticAnalyzerType.language;
		HashMap<String,String> pars = new HashMap<String, String>();
		pars.put(LanguageAnalyzer.LANGUAGE_PARAM_KEY, langType.toString());
		ElasticAnalyzer analyzer = buildAnalyzer(analyzerName, type, pars);
		analyzer.setParamsFromSettings(analyzerSettings);
		return analyzer;
		

		
	}
	
	
	
	 

	
	public static ElasticAnalyzer buildAnalyzer(String defName, ElasticAnalyzerType type , Map<String,String> params){
		
		
		if (defName.isEmpty()){
			if(params!=null){//we have custom params so this is a customized analyzer and we want to give it a propper name
				throw new IllegalArgumentException("No definition provided for custom analyzer");
			}else{
				defName = type.toString();
			}
		}
		
		switch (type) {
		 
		case standard:{
			StandardAnalyzer a = new StandardAnalyzer(params,defName);
			return a;
		}
		case simple:{
			SimpleAnalyzer a = new SimpleAnalyzer(defName);
			return a;
		}
		case keyword:{
			KeywordAnalyzer a = new KeywordAnalyzer(defName);
			return a;
		}
		case language:{
			LanguageAnalyzer a = new LanguageAnalyzer(params,defName);
			return a;
		}
		case pattern:{
			PatternAnalyzer a = new PatternAnalyzer(params,defName);
			return a;
		}
		case snowball:{
			SnowballAnalyzer a = new SnowballAnalyzer(params,defName);
			return a;
		}
		case stop:{
			StopAnalyzer a = new StopAnalyzer(params,defName);
			return a;
		}
		case whitespace:{
			WhitespaceAnalyzer a = new WhitespaceAnalyzer(defName);
			return a;
		}
		case custom:	{
			CustomAnalyzer a = new CustomAnalyzer(params,defName);
			return a;
		}
		case _void :
			return null;
		default:
			return null;
	}
	}
	
	
	
}
